package org.m3;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;


/**
 * Get Started!
 * @author yakovlev.yuriy@gmail.com
 * @author Dmitry Makeev
 */
public class TwoCards extends Activity implements OnClickListener {
    // We store cards names without extensions to array. Each card should have duplicate entry
    private Animals[] animals = new Animals[] {
    		Animals.cat, Animals.cat,
    		Animals.chicken, Animals.chicken, 
    		Animals.cow, Animals.cow,
    		Animals.dog, Animals.dog,
    		Animals.donkey, Animals.donkey,
    		Animals.duck, Animals.duck,
    		Animals.pig, Animals.pig,
    		Animals.sheep, Animals.sheep};
	private List<Animals> animalsList;

	// Reference to cards area
    private LinearLayout cardsPanel;
    // Counter to inspect number of guesses
    private int counter = 0;
    // Reference to previously selected card
    private ImageView selectedCard;
    // Timer start time
    private long startTime = 0;
    private int itemWidth;
    private int itemHeight;
    private int cards = 4;
    // This value corresponds to total amount of guesses, needed to be passed by player
    // We will decrement it value on every successful guess
    private int remainedGuesses;
    // timer
    private Count cdt;
    private TextView timer;
    private int timeout = 60*1000;
    // music
    private MediaPlayer mp;
    private Button btnGameList;
    private Button btnSpeaker;
    private Button btnNext;
    private Dialog dlgCorrect;
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        L10N.init(this.getResources());
        setContentView(R.layout.two_cards);
         
        initBtnGameList();
        initBtnSpeaker();
        initBtnNext();
        
        Display display = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
        itemWidth = (display.getOrientation()==0 ? display.getWidth() : display.getHeight()-55) / 4;
        itemHeight = (display.getOrientation()==0 ? display.getHeight() : display.getHeight()-55) / 7;
        
        mp = MediaPlayer.create(TwoCards.this, R.raw.t5);
        play();
    }
     
	@Override
	public void onClick(View v) {
		if(v.equals(btnGameList)) {
			finish();	
		} else if(v.equals(btnSpeaker)) {
    		Home.soundEnabled = !Home.soundEnabled;
    		btnSpeaker.setCompoundDrawablesWithIntrinsicBounds(null, TwoCards.this.getResources().getDrawable(Home.soundEnabled ? R.drawable.speaker : R.drawable.dspeaker), null, null);
    		if(!Home.soundEnabled && mp != null) {
    			mp.stop();
        		mp.release();
    		}
		} else if(v.equals(btnNext)) {
	   		cardsPanel.removeAllViews();
			counter = 0;
	        selectedCard = null;
	        startTime = 0;
	        cards += 4;
	        if(cards > animals.length) cards = 4;
	        play();
		}
	}
	
    // Dynamically add cards
    public void play() {
    	if(cdt != null) {
    		cdt.cancel();
    	}
    	remainedGuesses = cards / 2;
    	if(cards <= animals.length) {
	    	animalsList = new ArrayList<Animals>();
	    	for(int i=0; i<cards; i++) {
	    		animalsList.add(animals[i]);
	    	}
	    	Collections.shuffle(animalsList);
    	}
    	cardsPanel = (LinearLayout) findViewById(R.id.twoCards);	
        
    	
    	timer = new TextView(this);
    	timer.setTextAppearance(this, R.style.question);
    	timer.setTypeface(L10N.font);
        timer.setTextSize(36);
        timer.setText("01 : 00");
        timer.setPadding(0,40,0,0);
        timer.setGravity(Gravity.CENTER_HORIZONTAL);
        cardsPanel.addView(timer);
        
    	LinearLayout main = new LinearLayout(this);
    	main.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
    	main.setOrientation(LinearLayout.VERTICAL);
        main.setGravity(Gravity.CENTER_VERTICAL);
    	
    	LinearLayout row = new LinearLayout(this);
        row.setOrientation(LinearLayout.HORIZONTAL);
        row.setGravity(Gravity.CENTER_HORIZONTAL);
    	
        // For each card create default cover image and place it to game area
        for(int i=0; i<animalsList.size(); i++) {
        	if(i==4 || i==8 || i==12) {
        		main.addView(row);
        		row = new LinearLayout(this);
        		row.setOrientation(LinearLayout.HORIZONTAL);
                row.setGravity(Gravity.CENTER_HORIZONTAL);
        	}
        	final Animals animal = animalsList.get(i);
        	final ImageView card = new ImageView(this);
        	card.setLayoutParams(new GridView.LayoutParams(itemWidth, itemHeight));
            card.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
            card.setPadding(5,5,5,5);
        	card.setImageDrawable(this.getResources().getDrawable(R.drawable.cover));
        	card.setId(animal.getImage());
        	// After card will be selected we call appropriate method to process selection
            card.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View arg0) {
					// Show card real image, when it is pressed. Image will be displayed so long, as user will keep mouse button pressed
	                card.setImageDrawable(TwoCards.this.getResources().getDrawable(animal.getImage()));
	                cardSelected(card);
				}
            });
            // Add card to panel
            row.addView(card);
        }
        main.addView(row);
        cardsPanel.addView(main);
    }    
 
    
    // PRIVATE METHODS
    
    // On card selection we call this method to compare current card with previously saved one
    private void cardSelected(final ImageView card) {
        // If this is first user choice, we save start time to analyze how much time the quiz took
        if(startTime == 0) {
        	if(cdt == null) {
    			cdt = new TwoCards.Count(timeout, 100);
    		}
        	cdt.start();
            startTime = System.currentTimeMillis();
        }

        // If counter > 0 then we already selected card previously and need to compare them
        if(counter > 0) {
            // Both cards corresponds to the same picture, i.e. has the same names.
            // Also we check that user didn't press on the same card twice
            if(!selectedCard.equals(card) && selectedCard.getId() == card.getId()) {
                // Set done image for both cards and disable them
            	card.setImageDrawable(this.getResources().getDrawable(card.getId()));
                card.setEnabled(false);
            	selectedCard.setImageDrawable(this.getResources().getDrawable(card.getId()));
                selectedCard.setEnabled(false);

                // All cards were guessed successfully. Write into console the total time spent on quiz
                if(--remainedGuesses <= 0) {
                	getDlgCorrect().show();
                    new Thread(new Runnable() {
        				@Override
        				public void run() {
        					try {
        		            	Thread.sleep(2000);
        		            }catch(InterruptedException e) {
        		            }
        		            getDlgCorrect().dismiss();
        				}
                    }).start();
                    counter = 0;
                    selectedCard = null;
                	// Substract from current time, the start time and multiply on 1000, to have value in seconds
                    long spentTime = (System.currentTimeMillis() - startTime) / 1000;
                    System.out.println("Time spent on quiz is " + spentTime + " seconds.");
                    startTime = 0;
                    
                    // play again
                    cardsPanel.removeAllViews();
                    cards += 4;
                    play();
                }
                counter = 0;
                selectedCard = null;
                return;
            }
            // Selection was incorrect, reset counter
            counter = 0;
            selectedCard.setImageDrawable(TwoCards.this.getResources().getDrawable(R.drawable.cover));
            selectedCard = card;
        // Otherwise: the first card was selected, so we just save it and increase counter
        } else {
        	if(selectedCard != null) {
        		selectedCard.setImageDrawable(TwoCards.this.getResources().getDrawable(R.drawable.cover));
        	} 
            selectedCard = card;
            counter++;
        }
    }
    
    private Dialog getDlgCorrect() {
    	if(dlgCorrect == null) {
    		dlgCorrect = new Dialog(this);
    		dlgCorrect.setTitle("   " + this.getResources().getString(R.string.correct));
    		dlgCorrect.setContentView(R.layout.result);
            ImageView img = (ImageView) dlgCorrect.findViewById(R.id.imgStatus);
            img.setImageResource(R.drawable.correct);
    	}
    	return dlgCorrect;
    }
    
    private void initBtnGameList() {
    	if(btnGameList == null) {
    		btnGameList = (Button) findViewById(R.id.btnGameList);
    		btnGameList.setOnClickListener(this);
    	}
    }

    private void initBtnSpeaker() {
    	if(btnSpeaker == null) {
    		btnSpeaker = (Button) findViewById(R.id.btnSpeaker);
    		btnSpeaker.setOnClickListener(this);
    		btnSpeaker.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(Home.soundEnabled ? R.drawable.speaker : R.drawable.dspeaker), null, null);
    	}
    }

    private void initBtnNext() {
    	if(btnNext == null) {
    		btnNext = (Button) findViewById(R.id.btnNext);
    		btnNext.setOnClickListener(this);
    	}
    }
    
    class Count extends CountDownTimer {
    	
    	public Count(long millisInFuture, long countDownInterval) {
	      super(millisInFuture, countDownInterval);
	    }
	
	    public void onFinish() {
	    	final Dialog dialog = new Dialog(TwoCards.this);
    		dialog.setTitle("   " + TwoCards.this.getResources().getString(R.string.wrong));
            dialog.setContentView(R.layout.result);
            ImageView img = (ImageView) dialog.findViewById(R.id.imgStatus);
            img.setImageResource(R.drawable.wrong);
            dialog.show();
            new Thread(new Runnable() {
				@Override
				public void run() {
					try {
		            	Thread.sleep(1000);
		            }catch(InterruptedException e) {
		            }
		            dialog.dismiss();
				}
            }).start();
            counter = 0;
            selectedCard = null;
        	startTime = 0;
            cardsPanel.removeAllViews();
            cards = 4;
            play();
	    }
	
	    public void onTick(long millisUntilFinished) {
	    	if(millisUntilFinished <= 10000) {
	    		if(Home.soundEnabled && !mp.isPlaying()) {
	    			mp.start();
	    		}
	    	}
	    	timer.setText(formatTime(millisUntilFinished));
	    }

	    public String formatTime(long millis) {
	    	String output = "00 : 00";
	        long seconds = millis / 1000;
	        long minutes = seconds / 60;

	        seconds = seconds % 60;
	        minutes = minutes % 60;

	        String secondsD = String.valueOf(seconds);
	        String minutesD = String.valueOf(minutes);

	        if (seconds < 10)
	        	secondsD = "0" + seconds;
	        if (minutes < 10)
	        	minutesD = "0" + minutes;
	        output = minutesD + " : " + secondsD;
	        return output;
	    }
    
    }
    
	@Override
	public void onStop() {
		super.onStop();
    	if(cdt != null) {
    		cdt.cancel();
    	}
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
    	if(cdt != null) {
    		cdt.cancel();
    	}
	}

}
